package com.mirror.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Date;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXSource;

import org.ccil.cowan.tagsoup.Parser;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.mirror.client.LynchService;

public class LynchServiceImpl extends RemoteServiceServlet implements
		LynchService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2L;

	@Override
	public String getBusinessLynchBlock(Date date) {
		String baseURL = "http://www.artlebedev.ru/kovodstvo/business-lynch/";
		String businessLynchBlock = "";
		String url = baseURL + getDateFormatted(date);
		Transformer transformer = null;
		try 
		{
			System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.xsltc.trax.TransformerFactoryImpl");
			transformer = TransformerFactory.newInstance().newTransformer();
			DOMResult result = new DOMResult();
			URL pageURL = null;
			pageURL = new URL(url);
			BufferedReader reader = null;
			reader = new BufferedReader(new InputStreamReader(pageURL.openStream(), Charset.forName("UTF-8")));
			InputSource inputSource = new InputSource(reader);
			SAXSource saxSource = new SAXSource(new Parser(), inputSource);
			transformer.transform(saxSource, result);
			Node rootNode = result.getNode();
			Document document = (Document)rootNode;
			//Removing the Kovodstvo header
			NodeList tables = document.getElementsByTagName("table");
			Node header = tables.item(0);
			header.getParentNode().removeChild(header);
			//Removing top menu
			Node firstMenuLine = getElementdByTagNameAndClass(document, "div", "web");
			firstMenuLine.getParentNode().removeChild(firstMenuLine);
			Node mltb = getElementdByTagNameAndClass(document, "table", "branches");
			Node secondMenuLine = mltb.getParentNode();
			secondMenuLine.getParentNode().removeChild(secondMenuLine);
			mltb = getElementdByTagNameAndClass(document, "table", "branches");
			Node thirdMenuLine = mltb.getParentNode();
			thirdMenuLine.getParentNode().removeChild(thirdMenuLine);
			//Removing Week Preview
			Node weekPreview = getElementdByTagNameAndClass(document, "table", "week-preview");
			weekPreview.getParentNode().removeChild(weekPreview);
			//Removing Footer
			Node footerSpan = getElementdByTagNameAndClass(document, "span", "smaller");
			Node footer = footerSpan.getParentNode();
			footer.getParentNode().removeChild(footer);
			
			DOMImplementationLS domImplementation = (DOMImplementationLS) document.getImplementation();
		    LSSerializer lsSerializer = domImplementation.createLSSerializer();
			businessLynchBlock = lsSerializer.writeToString(document);			
		} catch (TransformerException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		}
		return businessLynchBlock;
	}
	
	//Here I will return only the first relevant element	
	private Node getElementdByTagNameAndClass(Document document, String tagName, String className)
	{
		Node result = null;
		NodeList tags = document.getElementsByTagName(tagName);
		int l = tags.getLength();
		if (tags.getLength() > 0)
		{
			for(int i=0; i<l; i++)
			{
				NamedNodeMap attributes = tags.item(i).getAttributes();
				int al = attributes.getLength();
				if (al>0)
				{
					for (int j=0; j<al; j++)
					{
						Node elementClass = attributes.getNamedItem("class");
						if (elementClass != null && elementClass.getNodeValue().equals(className))
						{
							result = tags.item(i);
							break;
						}
					}
				}
				if (result != null) break;
			}
		}
		
		return result;
	}

	@Override
	public String getDateFormatted(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		return ""+ year +"/" + month + "/" + day;
	}

}
